// Package service
// @Author: zhangdi
// @File: BackService
// @Version: 1.0.0
// @Date: 2023/6/26 16:30
package service

import (
	"bytes"
	"cscommon/comapis"
	"cscommon/comdto"
	"encoding/json"
	"errors"
	"ideatools/application/constant"
	"ideatools/application/constant/enums"
	"ideatools/application/pkgs/mylog"
	"ideatools/application/pkgs/utils"
	"ideatools/application/pkgs/yaml"
	"ideatools/setting"
	"io/ioutil"
	"net/http"
	"path/filepath"
	"strings"
	"time"
)

type HttpResp struct {
	Code  int    `json:"code"`
	Msg   string `json:"msg"`
	Data  any    `json:"data"`
	Extra any    `json:"extra,omitempty"`
}

// BackService 后端服务
type BackService struct {
	Authorization string
	//config        *dbservice.DbConfigService
	BackUrl string
}

func NewBackService() *BackService {
	url := setting.BackUrl
	if yaml.GetInt(constant.ConfigKeyIsDve) == 1 {
		url = setting.DevBackUrl
	}
	return &BackService{
		//config:        conf,
		BackUrl:       url,
		Authorization: yaml.GetString(constant.ConfigKeyBackAuthorization),
	}
}

// ApiLogin 登录
func (s *BackService) ApiLogin(dtoData comdto.UserDtoLogin) *HttpResp {
	res := s.SendPost(comapis.ApiUserLogin, dtoData)
	if res != nil && res.Code == enums.RespCodeOk {
		extras := res.Extra.([]any)
		Authorization := extras[0].(string)
		s.SetAuthorization(Authorization)
	}
	return res
}

// ApiGetNotice 获取系统通知
func (s *BackService) ApiGetNotice() *HttpResp {
	return s.SendPost(comapis.ApiSysGetNotice, nil)
}

// ApiShareApp 分享AI应用
func (s *BackService) ApiShareApp(data comdto.RequestAppAdd) *HttpResp {
	return s.SendPost(comapis.ApiAppShare, data)
}

// ApiAppAddUseNum 使用次数+1
func (s *BackService) ApiAppAddUseNum(data comdto.RequestAppUpdate) *HttpResp {
	return s.SendPost(comapis.ApiAppAddUseNum, data)
}

func (s *BackService) ApiAppGetList(extra comdto.FindExtra, Searchtext, TagIds string) *HttpResp {
	//var appList []comdto.AppInfo
	//搜索文本 LIKE查询
	if Searchtext != "" {
		Searchtext = "%" + Searchtext + "%"
	}

	//标签id LIKE查询
	if TagIds != "" {
		TagIds = "%" + TagIds + "%"
	}

	return s.SendPost(
		comapis.ApiAppList,
		&comdto.RequestAppGetList{
			Extra:      &extra,
			SearchText: Searchtext,
			TagId:      TagIds,
		})

}

// ApiAppTagGetList 获取标签列表
func (s *BackService) ApiAppTagGetList(extra comdto.FindExtra) *HttpResp {
	return s.SendPost(comapis.ApiAppTagList, comdto.RequestAppTagList{Extra: &extra})
	//s.ApiGetList(comapis.ApiAppTagList, comdto.RequestAppTagList{Extra: &extra}, &appTagList, &comdto.AppTagInfo{})
	//return appTagList
}

//ApiGetList 定义一个通用的API获取列表的方法
//func (s *BackService) ApiGetList(apiURL string, requestData interface{}, responseList interface{}, resultItem interface{}) (error, int64) {
//	response := s.SendPost(apiURL, requestData)
//	if response != nil && response.Data != nil && response.Code == enums.RespCodeOk {
//		responseListValue := reflect.ValueOf(responseList)
//		if responseListValue.Kind() != reflect.Ptr || responseListValue.Elem().Kind() != reflect.Slice {
//			return errors.New("responseList参数必须是切片的指针"), 0
//		}
//		responseListElem := reflect.Indirect(responseListValue.Elem())
//		responseListElemType := responseListElem.Type()
//
//		responseSlice := response.Data.([]interface{})
//		for _, item := range responseSlice {
//			jsonBytes, err := json.Marshal(item)
//			if err != nil {
//				// 错误处理
//				continue
//			}
//
//			itemValue := reflect.New(responseListElemType.Elem())
//			err = json.Unmarshal(jsonBytes, itemValue.Interface())
//			if err != nil {
//				// 错误处理
//				continue
//			}
//
//			responseListElem = reflect.Append(responseListElem, itemValue.Elem())
//		}
//
//		responseListValue.Elem().Set(responseListElem)
//		return nil, response.Extra.([]int64)[0]
//	}
//
//	return errors.New("获取列表失败"), 0
//}

// CheckLogin 是否已经登录
func (s *BackService) CheckLogin() *comdto.UserDtoInfo {
	resp := s.SendPost(comapis.ApiUserIsLogin, comdto.UserDtoIsLogin{Token: s.Authorization})
	if resp != nil && resp.Code == enums.RespCodeOk {
		if resp.Data != nil {
			jsonStr, err := json.Marshal(resp.Data)
			if err != nil {
				mylog.Error("1" + err.Error())
				return nil
			} else {
				userInfo := &comdto.UserDtoInfo{}
				err = json.Unmarshal(jsonStr, userInfo)
				if err != nil {
					mylog.Error("2" + err.Error())
					return nil
				}
				return userInfo
			}
		}
	}
	return nil
}

// ApiRegister 注册
func (s *BackService) ApiRegister(dtoData comdto.UserDtoRegister) *HttpResp {
	return s.SendPost(comapis.ApiUserRegister, dtoData)
}

// ApiGetPointsRecord 获取积分纪录
func (s *BackService) ApiGetPointsRecord(dtoData comdto.PointsRecordListDtoExtra) *HttpResp {
	mylog.Debug("ApiGetPointsRecord（）,", dtoData)
	return s.SendPost(comapis.ApiPointsGetRecord, dtoData)
}

// ApiSendEmailCode 发送邮件验证码
func (s *BackService) ApiSendEmailCode(dtoData comdto.EmailCodeDtoSend) *HttpResp {
	return s.SendPost(comapis.ApiEmailSendCode, dtoData)
}

func (s *BackService) GetZhijianProxyInfo() *HttpResp {
	return s.SendPost(comapis.ApiSysGetZhiJianproxyInfo, nil)
}

// ApiBackupUpload 数据备份接口
func (s *BackService) ApiBackupUpload() *HttpResp {
	info := s.CheckLogin()
	if info == nil {
		return s.formatResp(nil, errors.New("当前未登录，请先登录后操作"))
	}
	if !time.Now().Before(info.YunEnd) {
		return s.formatResp(nil, errors.New("当前云备份服务已到期"))
	}
	filePath := filepath.Join(utils.GetUserHomeDir(), setting.ProjectName, "data.db")
	err := utils.UploadFile(s.BackUrl+comapis.ApiBackupUpload, "file", filePath, s.Authorization)
	return s.formatResp(nil, err)
}

func (s *BackService) ApiBackupDownload(fileName string) *HttpResp {
	info := s.CheckLogin()
	if info == nil {
		return s.formatResp(nil, errors.New("当前未登录，请先登录后操作"))
	}

	targetFilePath := filepath.Join(utils.GetUserHomeDir(), setting.ProjectName, "data.db")
	err := utils.ParseResponseToFile(strings.ReplaceAll(s.BackUrl+comapis.ApiBackupDownload, ":filename", fileName), targetFilePath, s.Authorization)
	return s.formatResp(nil, err)
}

func (s *BackService) formatResp(data any, err error) *HttpResp {
	code := enums.RespCodeOk
	msg := "ok"
	if err != nil {
		code = enums.RespCodeError
		msg = err.Error()
	}
	return &HttpResp{Code: code, Msg: msg, Data: nil}
}

// ApiBackupGetList 获取备份列表
func (s *BackService) ApiBackupGetList() *HttpResp {
	return s.SendPost(comapis.ApiBackupGetList, make(map[string]string, 0))
}

// GetUpdateHistory 获取更新记录
func (s *BackService) GetUpdateHistory() *HttpResp {
	return s.SendPost(comapis.ApiSysGetUpdateList, make(map[string]string, 0))
}

// SendPost  发送 HTTP POST 请求
func (s *BackService) SendPost(urlAddress string, data any) *HttpResp {
	defer func() {
		if r := recover(); r != nil {
			// 在这里进行异常恢复的逻辑处理
			mylog.Error("SendPost 发生了panic:", r)
		}
	}()
	if data == nil {
		data = make(map[string]string, 0)
	}
	urlAddress = s.BackUrl + urlAddress
	SendJsonData, err := json.Marshal(&data)
	reader := bytes.NewReader(SendJsonData)
	req, err := http.NewRequest("POST", urlAddress, reader)
	mylog.Debug("url" + urlAddress)
	mylog.Debug("data", data)
	if err != nil {
		mylog.Error("SendPost() error" + err.Error())
		return nil
	}
	// 设置自定义请求头字段
	req.Header.Set("ContentType", "application/json")
	req.Header.Set("Authorization", "Bearer "+s.Authorization)

	client := &http.Client{}
	response, err := client.Do(req)
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)

	var RespData *HttpResp = &HttpResp{}

	err = json.Unmarshal(body, RespData)
	if err != nil {
		mylog.Error("SendPost() error" + err.Error())
		return &HttpResp{
			Code: 0,
			Msg:  err.Error(),
		}
	}
	return RespData
}

func (s *BackService) SetAuthorization(auth string) {
	yaml.Set(constant.ConfigKeyBackAuthorization, auth)
	s.Authorization = auth
}

func (s *BackService) GetAuthorization() string {
	return s.Authorization
}

func (s *BackService) GetBackUrl() string {
	return s.BackUrl
}
